/*!
 * \file TraderCTPMini.h
 * \project WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief CTP Mini交易接口实现
 * 
 * \details CTP Mini交易接口适配器，基于上期技术CTP Mini API实现
 *          提供期货交易的完整功能，专为中小型机构设计的轻量级实现
 *          支持期货、期权交易，提供订单管理、持仓查询、资金查询等功能
 *          采用异步回调机制，支持多线程安全操作
 */
#pragma once

#include <string>
#include <queue>
#include <stdint.h>

#include "../Includes/WTSTypes.h"
#include "../Includes/ITraderApi.h"
#include "../Includes/WTSCollection.hpp"

#include "../API/CTPMini1.5.8/ThostFtdcTraderApi.h"

#include "../Share/IniHelper.hpp"
#include "../Share/StdUtils.hpp"
#include "../Share/DLLHelper.hpp"

USING_NS_WTP;

/*!
 * \class TraderCTPMini
 * \brief CTP Mini交易接口实现类
 * 
 * \details CTP Mini交易接口适配器，继承自ITraderApi和CThostFtdcTraderSpi
 *          实现WonderTrader统一交易接口，封装CTP Mini API的具体实现
 *          
 *          主要功能：
 *          - 交易连接管理：支持前置服务器连接、断线重连
 *          - 用户认证登录：支持用户名密码登录、产品认证
 *          - 订单管理：支持订单提交、撤单、改单操作
 *          - 持仓查询：支持实时持仓查询、持仓明细查询
 *          - 资金查询：支持账户资金查询、保证金计算
 *          - 成交查询：支持历史成交查询、实时成交推送
 *          - 数据转换：WonderTrader数据结构与CTP数据结构互转
 *          - 异步查询：支持多线程异步查询，避免阻塞主线程
 *          - 错误处理：完善的错误处理和异常恢复机制
 *          
 *          CTP Mini特点：
 *          - 轻量级实现，适合中小型机构使用
 *          - 简化的API接口，降低接入门槛
 *          - 保持与标准CTP API的兼容性
 *          - 支持期货和期权交易
 *          
 * \note 使用前需要先初始化并连接到CTP Mini前置服务器
 * \warning 所有交易操作都是异步的，结果通过回调函数返回
 * \see ITraderApi, CThostFtdcTraderSpi
 */
class TraderCTPMini : public ITraderApi, public CThostFtdcTraderSpi
{
public:
	TraderCTPMini();
	virtual ~TraderCTPMini();

public:
	/*!
	 * \enum WrapperState
	 * \brief 交易接口状态枚举
	 * 
	 * \details 定义交易接口的各种连接和登录状态
	 */
	typedef enum
	{
		WS_NOTLOGIN,		///< 未登录状态
		WS_LOGINING,		///< 正在登录状态
		WS_LOGINED,			///< 已登录状态
		WS_LOGINFAILED,		///< 登录失败状态
		WS_CONFIRM_QRYED,	///< 结算单查询状态
		WS_CONFIRMED,		///< 结算单确认状态
		WS_ALLREADY			///< 全部就绪状态，可以进行交易
	} WrapperState;

private:
	/*!
	 * \brief 用户认证
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 向CTP Mini服务器发送用户认证请求
	 *          使用AppID和AuthCode进行产品认证
	 */
	int authenticate();

	/*!
	 * \brief 执行用户登录
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 向CTP Mini服务器发送用户登录请求
	 *          使用用户名和密码进行身份验证
	 */
	int doLogin();

	//////////////////////////////////////////////////////////////////////////
	//ITraderApi接口实现
public:
	/*!
	 * \brief 初始化交易接口
	 * \param params 初始化参数
	 * \return 成功返回true，失败返回false
	 * 
	 * \details 初始化CTP Mini交易接口，设置连接参数
	 *          必需参数：
	 *          - front: 交易前置服务器地址
	 *          - broker: 经纪商代码
	 *          - user: 用户名
	 *          - pass: 密码
	 *          
	 *          可选参数：
	 *          - appid: 应用程序标识
	 *          - authcode: 认证码
	 *          - flowdir: 流文件目录
	 *          - ctpmodule: CTP动态库模块名
	 *          - quick: 是否快速启动
	 */
	virtual bool init(WTSVariant* params) override;

	/*!
	 * \brief 释放交易接口资源
	 * 
	 * \details 清理所有资源，断开连接，停止工作线程
	 *          释放CTP API对象，清理数据缓存
	 */
	virtual void release() override;

	/*!
	 * \brief 注册交易事件监听器
	 * \param listener 事件监听器指针
	 * 
	 * \details 设置交易事件的回调处理器
	 *          用于接收交易相关的事件通知
	 */
	virtual void registerSpi(ITraderSpi *listener) override;

	/*!
	 * \brief 生成委托单号
	 * \param buffer 输出缓冲区
	 * \param length 缓冲区长度
	 * \return 成功返回true，失败返回false
	 * 
	 * \details 生成唯一的委托单号标识
	 *          格式：前置编号#会话编号#报单引用
	 */
	virtual bool makeEntrustID(char* buffer, int length) override;

	/*!
	 * \brief 连接到CTP Mini服务器
	 * 
	 * \details 建立与CTP Mini交易前置服务器的连接
	 *          启动异步查询工作线程
	 */
	virtual void connect() override;

	/*!
	 * \brief 断开与CTP Mini服务器的连接
	 * 
	 * \details 安全断开连接并清理资源
	 *          停止工作线程，释放API对象
	 */
	virtual void disconnect() override;

	/*!
	 * \brief 检查连接状态
	 * \return 已连接返回true，未连接返回false
	 * 
	 * \details 检查与CTP Mini服务器的连接状态
	 */
	virtual bool isConnected() override;

	/*!
	 * \brief 用户登录
	 * \param user 用户名
	 * \param pass 密码
	 * \param productInfo 产品信息
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 启动用户登录流程
	 *          先进行产品认证，再进行用户登录
	 */
	virtual int login(const char* user, const char* pass, const char* productInfo) override;

	/*!
	 * \brief 用户登出
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 向CTP Mini服务器发送用户登出请求
	 */
	virtual int logout() override;

	/*!
	 * \brief 提交订单
	 * \param eutrust 委托单对象
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 向CTP Mini服务器提交交易订单
	 *          支持限价单、市价单等多种订单类型
	 */
	virtual int orderInsert(WTSEntrust* eutrust) override;

	/*!
	 * \brief 订单操作（撤单/改单）
	 * \param action 订单操作对象
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 对已提交的订单进行撤单或改单操作
	 */
	virtual int orderAction(WTSEntrustAction* action) override;

	/*!
	 * \brief 查询资金账户
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 查询投资者资金账户信息
	 *          包括可用资金、保证金、盈亏等
	 */
	virtual int queryAccount() override;

	/*!
	 * \brief 查询持仓信息
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 查询投资者持仓信息
	 *          包括持仓数量、持仓成本、浮动盈亏等
	 */
	virtual int queryPositions() override;

	/*!
	 * \brief 查询订单信息
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 查询当日所有订单信息
	 *          包括已成交、部分成交、未成交订单
	 */
	virtual int queryOrders() override;

	/*!
	 * \brief 查询成交信息
	 * \return 成功返回0，失败返回错误码
	 * 
	 * \details 查询当日所有成交信息
	 *          包括成交价格、成交数量、成交时间等
	 */
	virtual int queryTrades() override;

	//////////////////////////////////////////////////////////////////////////
	//CTP Mini交易接口回调实现
public:
	/*!
	 * \brief 前置连接成功回调
	 * 
	 * \details 当与CTP Mini前置服务器连接成功时调用
	 *          开始用户认证流程
	 */
	virtual void OnFrontConnected() override;

	/*!
	 * \brief 前置连接断开回调
	 * \param nReason 断开原因
	 * 
	 * \details 当与CTP Mini前置服务器连接断开时调用
	 *          更新连接状态，通知上层应用
	 */
	virtual void OnFrontDisconnected(int nReason) override;

	/*!
	 * \brief 心跳警告回调
	 * \param nTimeLapse 距离上次心跳的时间间隔
	 * 
	 * \details 当心跳超时时调用，记录警告信息
	 */
	virtual void OnHeartBeatWarning(int nTimeLapse) override;

	/*!
	 * \brief 用户认证响应回调
	 * \param pRspAuthenticateField 认证响应信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理用户认证响应，认证成功后进行用户登录
	 */
	virtual void OnRspAuthenticate(CThostFtdcRspAuthenticateField *pRspAuthenticateField, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 用户登录响应回调
	 * \param pRspUserLogin 登录响应信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理用户登录响应，保存会话信息，初始化缓存
	 */
	virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 用户登出响应回调
	 * \param pUserLogout 登出信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理用户登出响应，更新登录状态
	 */
	virtual void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 资金账户查询响应回调
	 * \param pTradingAccount 资金账户信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理资金账户查询响应，转换为WonderTrader格式
	 */
	virtual void OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 订单提交响应回调
	 * \param pInputOrder 输入订单信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理订单提交响应，通知上层应用订单状态
	 */
	virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 订单操作响应回调
	 * \param pInputOrderAction 订单操作信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理订单操作响应，通知上层应用操作结果
	 */
	virtual void OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 持仓查询响应回调
	 * \param pInvestorPosition 持仓信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理持仓查询响应，转换为WonderTrader格式
	 */
	virtual void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 成交查询响应回调
	 * \param pTrade 成交信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理成交查询响应，转换为WonderTrader格式
	 */
	virtual void OnRspQryTrade(CThostFtdcTradeField *pTrade, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 订单查询响应回调
	 * \param pOrder 订单信息
	 * \param pRspInfo 响应信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理订单查询响应，转换为WonderTrader格式
	 */
	virtual void OnRspQryOrder(CThostFtdcOrderField *pOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 错误响应回调
	 * \param pRspInfo 错误信息
	 * \param nRequestID 请求ID
	 * \param bIsLast 是否最后一条
	 * 
	 * \details 处理CTP Mini API返回的错误信息
	 */
	virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) override;

	/*!
	 * \brief 订单回报推送
	 * \param pOrder 订单信息
	 * 
	 * \details 接收CTP Mini推送的订单状态变化通知
	 *          实时更新订单状态，通知上层应用
	 */
	virtual void OnRtnOrder(CThostFtdcOrderField *pOrder) override;

	/*!
	 * \brief 成交回报推送
	 * \param pTrade 成交信息
	 * 
	 * \details 接收CTP Mini推送的成交通知
	 *          实时更新持仓和资金，通知上层应用
	 */
	virtual void OnRtnTrade(CThostFtdcTradeField *pTrade) override;

	/*!
	 * \brief 订单提交错误回报
	 * \param pInputOrder 输入订单信息
	 * \param pRspInfo 错误信息
	 * 
	 * \details 接收CTP Mini推送的订单提交错误通知
	 */
	virtual void OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo) override;

protected:
	/*!
	 * \brief 检查响应信息是否包含错误
	 * \param pRspInfo 响应信息
	 * \return 有错误返回true，无错误返回false
	 * 
	 * \details 检查CTP Mini API返回的响应信息中是否包含错误
	 */
	bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);

	// 数据类型转换函数 - WonderTrader到CTP Mini
	int wrapPriceType(WTSPriceType priceType, bool isCFFEX = false);	///< 价格类型转换
	int wrapDirectionType(WTSDirectionType dirType, WTSOffsetType offType);	///< 买卖方向转换
	int wrapOffsetType(WTSOffsetType offType);	///< 开平标志转换
	int	wrapTimeCondition(WTSTimeCondition timeCond);	///< 时间条件转换
	int wrapActionFlag(WTSActionFlag actionFlag);	///< 操作标志转换

	// 数据类型转换函数 - CTP Mini到WonderTrader
	WTSPriceType		wrapPriceType(TThostFtdcOrderPriceTypeType priceType);	///< 价格类型转换
	WTSDirectionType	wrapDirectionType(TThostFtdcDirectionType dirType, TThostFtdcOffsetFlagType offType);	///< 买卖方向转换
	WTSDirectionType	wrapPosDirection(TThostFtdcPosiDirectionType dirType);	///< 持仓方向转换
	WTSOffsetType		wrapOffsetType(TThostFtdcOffsetFlagType offType);	///< 开平标志转换
	WTSTimeCondition	wrapTimeCondition(TThostFtdcTimeConditionType timeCond);	///< 时间条件转换
	WTSOrderState		wrapOrderState(TThostFtdcOrderStatusType orderState);	///< 订单状态转换

	// 数据对象创建函数
	WTSOrderInfo*	makeOrderInfo(CThostFtdcOrderField* orderField);	///< 创建订单信息对象
	WTSEntrust*		makeEntrust(CThostFtdcInputOrderField *entrustField);	///< 创建委托对象
	WTSError*		makeError(CThostFtdcRspInfoField* rspInfo);	///< 创建错误对象
	WTSTradeInfo*	makeTradeRecord(CThostFtdcTradeField *tradeField);	///< 创建成交记录对象

	/*!
	 * \brief 生成委托单号
	 * \param frontid 前置编号
	 * \param sessionid 会话编号
	 * \param orderRef 报单引用
	 * \return 委托单号字符串
	 * 
	 * \details 根据前置编号、会话编号和报单引用生成唯一的委托单号
	 */
	std::string		generateEntrustID(uint32_t frontid, uint32_t sessionid, uint32_t orderRef);

	/*!
	 * \brief 解析委托单号
	 * \param entrustid 委托单号
	 * \param frontid 输出前置编号
	 * \param sessionid 输出会话编号
	 * \param orderRef 输出报单引用
	 * \return 解析成功返回true，失败返回false
	 * 
	 * \details 从委托单号中解析出前置编号、会话编号和报单引用
	 */
	bool			extractEntrustID(const char* entrustid, uint32_t &frontid, uint32_t &sessionid, uint32_t &orderRef);

	/*!
	 * \brief 生成请求ID
	 * \return 唯一的请求ID
	 * 
	 * \details 生成CTP Mini API调用的请求标识，确保线程安全
	 */
	uint32_t		genRequestID();

protected:
	// 连接配置参数
	std::string		m_strBroker;	///< 经纪商代码
	std::string		m_strFront;		///< 前置服务器地址

	std::string		m_strUser;		///< 用户名
	std::string		m_strPass;		///< 密码

	std::string		m_strAppID;		///< 应用程序标识
	std::string		m_strAuthCode;	///< 认证码
	std::string		m_strFlowDir;	///< 流文件目录

	std::string		m_strProdInfo;	///< 产品信息

	bool			m_bQuickStart;	///< 是否快速启动

	std::string		m_strTag;		///< 标签

	std::string		m_strUserName;	///< 用户名称

	// 回调和管理对象
	ITraderSpi*		m_sink;			///< 事件监听器
	uint64_t		m_uLastQryTime;	///< 上次查询时间

	// 会话信息
	uint32_t					m_lDate;		///< 交易日
	TThostFtdcFrontIDType		m_frontID;		///< 前置编号
	TThostFtdcSessionIDType		m_sessionID;	///< 会话编号
	std::atomic<uint32_t>		m_orderRef;		///< 报单引用

	WrapperState				m_wrapperState;	///< 接口状态

	// CTP Mini API对象
	CThostFtdcTraderApi*		m_pUserAPI;		///< CTP Mini交易API对象
	std::atomic<uint32_t>		m_iRequestID;	///< 请求ID计数器

	// 数据缓存
	typedef WTSHashMap<std::string> PositionMap;
	PositionMap*				m_mapPosition;	///< 持仓映射表
	WTSArray*					m_ayTrades;		///< 成交数组
	WTSArray*					m_ayOrders;		///< 订单数组
	WTSArray*					m_ayPosDetail;	///< 持仓明细数组
	WTSArray*					m_ayFunds;		///< 资金数组

	IBaseDataMgr*				m_bdMgr;		///< 基础数据管理器

	// 异步查询管理
	typedef std::queue<CommonExecuter>	QueryQue;
	QueryQue				m_queQuery;		///< 查询队列
	bool					m_bInQuery;		///< 是否正在查询
	StdUniqueMutex			m_mtxQuery;		///< 查询互斥锁
	uint64_t				m_lastQryTime;	///< 上次查询时间

	// 线程管理
	bool					m_bStopped;		///< 停止标志
	StdThreadPtr			m_thrdWorker;	///< 工作线程

	// 动态库管理
	std::string		m_strModule;	///< 模块路径
	DllHandle		m_hInstCTP;		///< CTP Mini动态库句柄
	typedef CThostFtdcTraderApi* (*CTPCreator)(const char *);
	CTPCreator		m_funcCreator;	///< CTP Mini API创建函数

	IniHelper		m_iniHelper;	///< INI配置文件助手
};
